package master.quantumComputerIO.gate;

import gates.*;

import java.awt.GridLayout;
import java.io.File;
import java.lang.reflect.*;
import java.net.*;
import java.util.*;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class QuantumGateIO {
	public static Class getGateClass(String filename) throws GateException {
		//try to get the gate class
		//if(!filename.endsWith(".class"))
			//throw new GateException("File specified not a .class file");
		try{
			Class c = Class.forName(filename);
			return c;
		}catch(ClassNotFoundException e){
			throw new GateException("Not able to load gate class "+e.getMessage());
		}catch(NullPointerException e){
			throw new GateException("Unable to locate file: "+filename);
		}
		
	}
	public static Class [] getGatesFromPackageStable(){
		return new Class []{
				Cnot.class,
				CondPhaseShift.class,
				ControlledPhaseShift.class,
				//CPhaseShift.class,
				FullHadamard.class,
				FullQuantumAdder.class,
				Grover.class,
				Hadamard.class,
				Measure.class,
				Oracle.class,
				PhaseShift.class,
				QuantumAdder.class,
				QuantumFourier.class,
				RippleCarryAdder.class,
				Shors.class,
				SwapGate.class,
				ToffoliGate.class
		};
	}
	
	/**
	 * Depricated method which scraped the source folder looking for class files
	 * @param directory
	 * @return
	 * @throws GateException
	 */
	public static Class [] getGatesFromPackage(String directory) throws GateException{
		File f = new File(directory);
		//search the directory of the package for .class files:
		f = new File(f.getAbsolutePath());
		//System.out.println(f.getAbsolutePath() +" is dir? " + f.isDirectory());
		File [] subfiles = f.listFiles();
		List <Class> eligibleClazzes = new ArrayList<Class>();
		for(File sub : subfiles){
			//System.out.println(sub.getName());
			if(sub.getName().endsWith(".class"))
				try{
					Class clazz =  getGateClass( f.getName()+"."+ sub.getName().replace(".class", "")  );
					if(QuantumGate.class.isAssignableFrom(clazz) && !QuantumGate.class.equals(clazz))
						eligibleClazzes.add(clazz);
				}catch(GateException e){
					
				}
				
		}
		Class [] clazz = new Class[eligibleClazzes.size()];
		for(int i = 0 ; i < clazz.length ; i++){
			clazz[i] = eligibleClazzes.get(i);
		}
		return clazz;
	}
	public static String [] getConstructorAnnotation(Class gateClass, int prefferedConstructor) throws GateException{
		//TODO prefferedConstructor does nothing!
		Constructor [] c = gateClass.getConstructors();
		
		int pre = 0;
		if(prefferedConstructor >= 0 && prefferedConstructor < c.length)
			pre = prefferedConstructor;
		
		if(c.length == 0) throw new GateException("uninitialisable gate: " + gateClass.getName());
		
		String [] annotation = new String[c[0].getAnnotations().length];
		for(int i = 0 ; i < c[0].getAnnotations().length ; i++){
			annotation[i] = c[0].getAnnotations()[i].toString();
		}
		return annotation;
	}
	public static Class [] getConstructorTypes(Class gateClass,int prefferedConstructor) throws GateException{
		Constructor [] c = gateClass.getConstructors();
		if(prefferedConstructor >= 0 && prefferedConstructor < c.length)
			c[prefferedConstructor].getParameterTypes();
		if(c.length == 0) throw new GateException("uninitialisable gate");
		return c[0].getParameterTypes();//will return default constructor
	}
}
